/*
 * Listener.cpp
 *
 *  Created on: 2.4.2011
 *      Author: Tomas Srna
 */

#include "Listener.h"

#define BUF_SIZE 1024

Listener::Listener(IFile * f, int p,
		std::ostream& logr)	: port(p), fs(*f), logger(logr) {}

void Listener::run ()
{
	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if(sock<0) throw "Error opening socket.";

	// Set to non-blocking
	/*if(0!=fcntl(sock, F_SETFL, O_NONBLOCK))
		throw "Error setting socket to non-blocking";*/

	// Bind
	bzero(&server, sizeof(server));
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = INADDR_ANY;
	server.sin_port = htons(port);
	if(0 != bind(sock, (struct sockaddr*)&server, sizeof(server)))
		throw "Error binding socket to port";

	logger << "Listening on port " << port << std::endl;

	// Samotna komunikacia
	char buf[BUF_SIZE];
	char ipaddr[INET_ADDRSTRLEN];
	int len;
	struct sockaddr_in from;
	socklen_t fromlen = sizeof(struct sockaddr_in);
	while(true)
	{
		len = recvfrom(sock, buf, BUF_SIZE, 0,
			(struct sockaddr*)&from, &fromlen);
		if(len > 0)
		{
			inet_ntop(AF_INET, &(from.sin_addr), ipaddr, INET_ADDRSTRLEN);
			logger << "Connection received from " << ipaddr << ":"
					<< from.sin_port << std::endl;
			Packet p(buf, len);
			logger << "Init packet: " << p << std::endl;
			Transfer * t = TransferFactory::factory
					(p, fs, from, logger);
			pthread_t thr;
			thr = pthread_create(&thr, NULL,
					(void*(*)(void*))Transfer::proc, t);
			threads.push_back(thr);
		}
		//usleep(200);
	}
	std::vector<pthread_t>::iterator tit;
	for(tit = threads.begin(); tit != threads.end(); tit++)
	{
		pthread_join(*tit, NULL);
	}
}

